/*
 * @Author: 晴鸢. 3013433857@qq.com
 * @Date: 2025-09-10 18:58:52
 * @LastEditors: 晴鸢. 3013433857@qq.com
 * @LastEditTime: 2025-09-11 14:49:19
 * @FilePath: /Learn/signal_catch/mysignal.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <cstring>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;
// pending位图，什么时候从1-> 0
void PrintPending()
{
    sigset_t set;
    sigpending(&set);
    for (int signo = 1; signo <= 31; signo++)
    {
        if (sigismember(&set, signo))
            cout << "1";
        else
            cout << "0";
    }
    cout << endl;
}

void handler(int signo)
{
    cout << "catch a signo,signal number:" << signo << endl;
    while (1)
    {
        PrintPending();
        sleep(1);
    }
}

void test1()
{
    struct sigaction act, oact;
    memset(&act, 0, sizeof(act));
    memset(&oact, 0, sizeof(oact));

    act.sa_handler = handler;
    sigaction(2, &act, &oact);
    while (1)
    {
        cout << "I am a process:" << getpid() << endl;
        sleep(1);
    }
}

int flag = 0;
void handler1(int signo)
{
    cout << "catch a signo,signal number:" << signo << endl;
    flag = 1;
}
void test2()
{
    signal(2, handler1);
    // 在优化条件下，flag变量可能直接优化到cpu内的寄存器中，并直接将值置为1
    while (!flag)
        ;
    cout << "process quit normal" << endl;
}

void handler2(int signo)
{
    sleep(5);
    pid_t rid;
    // 以非阻塞的方式等待任意一个子进程退出
    while ((rid = waitpid(-1, nullptr, WNOHANG)) > 0)
    {
        cout << "I am process:" << getpid()
             << "catch a signo:" << signo << "child process quit:" << rid << endl;
    }
}
void test3()
{
    signal(17, handler2); //
    for (int i = 0; i < 10; i++)
    {
        pid_t id = fork();
        if (id == 0)
        {
            while(1)
            {
                cout << "I am a child process:" << getpid() << ",ppid:" << getppid() << endl;
                sleep(3);
                break;
            }
            cout << "child quit" << endl;
            exit(0);
        }
    }
    while (1)
    {
        cout << "I am father process:" << getpid() << endl;
        sleep(1);
    }
}
int main()
{
    // test1();  查看信号被处理时，对应的信号是否会被添加到block表中
    // test2();  查看编译器的优化功能
    test3();
    return 0;
}